Azure Firewall/Template - Inspecting traffic to PE with Azure Firewall/DedicatedPeVnet.tf (366 lines of code) (raw):
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=2.46.0"
}
}
}
provider "azurerm" {
features {}
}
data "azurerm_client_config" "current" {}
resource "random_string" "random" {
length = 6
special = false
upper = false
}
resource "random_password" "password" {
length = 12
lower = true
numeric = true
special = true
upper = true
}
//Resource Group DedicatedPEVnet
resource "azurerm_resource_group" "rg" {
name = "DedicatedPEVnet"
location = "eastus2"
}
//Keyvault
resource "azurerm_key_vault" "mykeyvault" {
name = "${random_string.random.result}-kv"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
purge_protection_enabled = false
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
secret_permissions = [
"List",
"Set",
"Get",
]
}
}
//VM Secret
resource "azurerm_key_vault_secret" "vmsecret" {
name = "AzureUser"
value = "${random_password.password.result}"
key_vault_id = azurerm_key_vault.mykeyvault.id
}
//MySql Secret
resource "azurerm_key_vault_secret" "mysqlsecret" {
name = "mysqladmin"
value = "${random_password.password.result}"
key_vault_id = azurerm_key_vault.mykeyvault.id
}
//MySQL PaaS Service
resource "azurerm_mysql_server" "mysql" {
name = "${random_string.random.result}-mysql"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
version = "8.0"
administrator_login = "mysqladmin"
administrator_login_password = "${random_password.password.result}"
ssl_enforcement_enabled = "true"
sku_name = "GP_Gen5_2"
}
//MySQL Private Endpoint
resource "azurerm_private_endpoint" "mysqlpe" {
name = "${random_string.random.result}-endpoint"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = azurerm_subnet.MySQL.id
private_service_connection {
name = "${random_string.random.result}-privateserviceconnection"
private_connection_resource_id = azurerm_mysql_server.mysql.id
subresource_names = [ "mysqlServer" ]
is_manual_connection = false
}
}
//Public IPs (Firewall)
resource "azurerm_public_ip" "transitip" {
name = "FWTransitIP"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Static"
sku = "Standard"
}
//Firewall Policy Premium
resource "azurerm_firewall_policy" "FwPolicy" {
name = "FwPolicy"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku = "Premium"
private_ip_ranges = ["10.10.10.0/24","10.10.11.0/24"]
}
//Firewall Policy Rule Collections and Rules
resource "azurerm_firewall_policy_rule_collection_group" "FwLabRcg" {
name = "FwLabRcg"
firewall_policy_id = azurerm_firewall_policy.FwPolicy.id
priority = 600
application_rule_collection {
name = "app_rule_collection1"
priority = 500
action = "Allow"
rule {
name = "app_rule_collection1_rule1"
protocols {
type = "Http"
port = 80
}
protocols {
type = "Https"
port = 443
}
source_addresses = ["10.10.11.0/24"]
destination_fqdns = ["*.microsoft.com"]
}
rule {
name = "app_rule_collection1_rule2"
protocols {
type = "Https"
port = 443
}
source_addresses = ["10.10.11.0/24"]
destination_fqdns = ["${azurerm_mysql_server.mysql.name}.mysql.database.azure.com"]
}
}
network_rule_collection {
name = "network_rule_collection1"
priority = 400
action = "Deny"
rule {
name = "network_rule_collection1_rule1"
protocols = ["TCP","UDP"]
source_addresses = ["10.10.11.0/24"]
destination_addresses = ["8.8.8.8"]
destination_ports = ["80","443"]
}
}
network_rule_collection {
name = "network_rule_collection2"
priority = 395
action = "Allow"
rule {
name = "network_rule_collection2_rule1"
protocols = ["TCP"]
source_addresses = ["10.10.11.0/24"]
destination_addresses = ["10.10.12.4/32"]
destination_ports = ["443","3306"]
}
}
nat_rule_collection {
name = "nat_rule_collection1"
priority = 300
action = "Dnat"
rule {
name = "nat_rule_collection1_rule1"
protocols = ["TCP","UDP"]
source_addresses = ["*"]
destination_address = azurerm_public_ip.transitip.ip_address
destination_ports = ["3389"]
translated_address = "10.10.11.4"
translated_port = "3389"
}
}
}
//Route Tables (UDRs)
resource "azurerm_route_table" "Spoke1RT" {
name = "Spoke1RT"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
disable_bgp_route_propagation = "false"
route {
name = "DefaultRoute"
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = "10.10.10.4"
}
route {
name = "MySqlPE"
address_prefix = "10.10.12.4/32"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = "10.10.10.4"
}
}
//Hub Vnet
resource "azurerm_virtual_network" "hubvnet" {
name = "HubVnet"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["10.10.10.0/24"]
}
resource "azurerm_subnet" "AzureFirewallSubnet" {
name = "AzureFirewallSubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.hubvnet.name
address_prefixes = ["10.10.10.0/26"]
}
//Spoke Vnet (VM Vnet)
resource "azurerm_virtual_network" "spokevnet1" {
name = "SpokeVnet1"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["10.10.11.0/24"]
}
resource "azurerm_subnet" "AppSubnet" {
name = "AppSubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.spokevnet1.name
address_prefixes = ["10.10.11.0/27"]
}
//PE Vnet
resource "azurerm_virtual_network" "pevnet" {
name = "PeVnet"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["10.10.12.0/24"]
}
resource "azurerm_subnet" "MySQL" {
name = "mysqlsubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.pevnet.name
address_prefixes = ["10.10.12.0/27"]
}
//Route Table + Subnet Association
resource "azurerm_subnet_route_table_association" "AppSubnetRT" {
subnet_id = azurerm_subnet.AppSubnet.id
route_table_id = azurerm_route_table.Spoke1RT.id
}
//Hub and Spoke Vnet Peering
resource "azurerm_virtual_network_peering" "HubToSpoke1" {
name = "HubToSpoke1"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.hubvnet.name
remote_virtual_network_id = azurerm_virtual_network.spokevnet1.id
}
resource "azurerm_virtual_network_peering" "Spoke1ToHub" {
name = "HubToSpoke1"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.spokevnet1.name
remote_virtual_network_id = azurerm_virtual_network.hubvnet.id
}
//Hub and PE Vnet Peering
resource "azurerm_virtual_network_peering" "HubToPe" {
name = "HubToPE"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.hubvnet.name
remote_virtual_network_id = azurerm_virtual_network.pevnet.id
}
resource "azurerm_virtual_network_peering" "PeToHub" {
name = "PeToHub"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.pevnet.name
remote_virtual_network_id = azurerm_virtual_network.hubvnet.id
}
//Azure Firewall Premium
resource "azurerm_firewall" "azfw" {
name = "azfw"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
firewall_policy_id = azurerm_firewall_policy.FwPolicy.id
sku_tier = "Premium"
sku_name = "AZFW_VNet"
ip_configuration {
name = "transitconfig"
subnet_id = azurerm_subnet.AzureFirewallSubnet.id
public_ip_address_id = azurerm_public_ip.transitip.id
}
}
//AppVm1 Network Interface
resource "azurerm_network_interface" "AppVm1Nic1" {
name = "AppVm1Nic1"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "AppVmNicConfig1"
subnet_id = azurerm_subnet.AppSubnet.id
private_ip_address_allocation = "Dynamic"
}
}
//AppVm1
resource "azurerm_virtual_machine" "AppVm1" {
name = "AppVm1"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.AppVm1Nic1.id]
vm_size = "Standard_DS1_V2"
storage_image_reference {
publisher = "MicrosoftWindowsDesktop"
offer = "windows-11"
sku = "win11-22h2-pro"
version = "latest"
}
storage_os_disk {
name = "myosdisk1"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "appvm1"
admin_username = "AzureUser"
admin_password = "${random_password.password.result}"
}
os_profile_windows_config {
}
}
//Azure Private DNS Zone (mysql.database.azure.com) and A record
resource "azurerm_private_dns_zone" "mysqlprivdnszone" {
name = "privatelink.mysql.database.azure.com"
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_private_dns_a_record" "mysqldnsrecord" {
name = azurerm_mysql_server.mysql.name
zone_name = azurerm_private_dns_zone.mysqlprivdnszone.name
resource_group_name = azurerm_resource_group.rg.name
ttl = 300
records = ["10.10.12.4"]
}
resource "azurerm_private_dns_zone_virtual_network_link" "example" {
name = "SpokeVnet1Link"
resource_group_name = azurerm_resource_group.rg.name
private_dns_zone_name = azurerm_private_dns_zone.mysqlprivdnszone.name
virtual_network_id = azurerm_virtual_network.spokevnet1.id
}
//Log Analytics Workspace used by the Firewall's Diagnostic Settings
resource "azurerm_log_analytics_workspace" "DiagSettingsLaw" {
name = "DiagSettingsLaw"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku = "PerGB2018"
retention_in_days = 30
}
// Firewall's Diagnostic Settings (Resource Specific Logs)
resource "azurerm_monitor_diagnostic_setting" "azfw-diag" {
name = "RsFwLogDedicatedPeVnet"
target_resource_id = azurerm_firewall.azfw.id
log_analytics_workspace_id = azurerm_log_analytics_workspace.DiagSettingsLaw.id
log_analytics_destination_type = "Dedicated"
log {
category = "AZFWApplicationRule"
enabled = true
retention_policy {
enabled = true
}
}
log {
category = "AZFWNetworkRule"
enabled = true
retention_policy {
enabled = true
}
}
metric {
category = "AllMetrics"
enabled = false
retention_policy {
enabled = false
}
}
}